package marmalius.object.door;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.ArrayList;

import marmalius.Player;
import marmalius.PlayerHandler;
import marmalius.client;
import marmalius.map.MapService;
import marmalius.tools.DBService;
import marmalius.tools.LogService;

/*
private final int id_doors[] = {
	131, 134, 135, 136,
	1516, 1517, 1519, 1528, 1530, 1531, 1533, 1534, 1536, 1551, 1553, 1591,
	2882, 2883,
	3014, 3015, 3016, 3017, 3018, 3019, 3506, 3507,
	4487, 4490, 4491,
	5174, 5183, 5186,
	7320,
	9337,
	11470, 11712, 11707, 11708, 11714, 11715, 11716, 11721,
	12348, 12349, 12350, 12986, 12987,
	13001,
	14729
};
*/

public class DoorService {
	private static final DoorService instance = new DoorService();
	private List<Door> doors;
	private List<Integer> doorIDs;
	
	public DoorService() {
		doors = new ArrayList<Door>();
		doorIDs = new ArrayList<Integer>();
	}
	
	public boolean loadDoor() {
		doors.clear();
		doorIDs.clear();
		
		int nb = 0;
		try {
			ResultSet rs = DBService.getInstance().doQuery("SELECT * FROM obj_doors");
			while (rs.next()) {
				if (!doorIDs.contains(rs.getInt("id1")))
					doorIDs.add(rs.getInt("id1"));
				if (!doorIDs.contains(rs.getInt("id2")))
					doorIDs.add(rs.getInt("id2"));
				
				doors.add(new Door(rs.getInt("id1"), rs.getInt("x1"), rs.getInt("y1"), rs.getByte("heightlevel"), rs.getByte("f1"), rs.getInt("id2"), rs.getInt("x2"), rs.getInt("y2"), rs.getByte("f2")));
				nb++;
			}
			
		}
		catch (SQLException ex) {
			LogService.getInstance().logError("can't load obj_doors");
			LogService.getInstance().logError(ex.getMessage());
			return false;
		}
		LogService.getInstance().logInfo("loaded "+nb+" obj_doors");
		return true;
	}
	
 	public void actionDoor(int doorID, int coordX, int coordY, byte heightLevel) {
		Door door = getDoor(doorID, coordX, coordY, heightLevel);
		if (door == null) {
			door = new Door(doorID, coordX, coordY, heightLevel, (byte)0, -1, coordX, coordY, (byte)0);
			try {
				DBService.getInstance().doExecute("INSERT INTO obj_doors (x1, y1, x2, y2, id1, heightlevel) VALUE ("+coordX+", "+coordY+", "+coordX+", "+coordY+", "+doorID+", "+heightLevel+")");
			}
			catch (SQLException e) {}
			doors.add(door);
			LogService.getInstance().logDebug("Unknow Door, create temporarily one.");
		}
		door.changePosition();
		if (door.isFirstPosition())
			MapService.getInstance().removeObject(door);
		else
			MapService.getInstance().addObject(door);
		updateDoorShow(door);
	}
	
	public void updateDoorShow(Door door) {
		if (door.isFirstPosition()) {
			if (door.getCoordX() != door.getCoordX2() || door.getCoordY() != door.getCoordY2())
				PlayerHandler.getInstance().removeObjectAll(door.getCoordX2(), door.getCoordY2(), door.getHeightLevel());
			PlayerHandler.getInstance().replaceObjectAll(door.getDoorID1(), door.getCoordX(), door.getCoordY(), door.getHeightLevel(), door.getDoorFace1(), 0);
		}
		else {
			if (door.getCoordX() != door.getCoordX2() || door.getCoordY() != door.getCoordY2())
				PlayerHandler.getInstance().removeObjectAll(door.getCoordX(), door.getCoordY(), door.getHeightLevel());
			PlayerHandler.getInstance().replaceObjectAll(door.getDoorID2(), door.getCoordX2(), door.getCoordY2(), door.getHeightLevel(), door.getDoorFace2(), 0);
		}
	}
	
	public void updateDoorShowPlayer(Player player, Door door) {
		if (door.isFirstPosition()) {
			if (door.getCoordX() != door.getCoordX2() || door.getCoordY() != door.getCoordY2())
				((client)player).replaceObject(0, door.getCoordX2(), door.getCoordY2(), 0, 0);
			((client)player).replaceObject(door.getDoorID1(), door.getCoordX(), door.getCoordY(), door.getDoorFace1(), 0);
		}
		else {
			if (door.getCoordX() != door.getCoordX2() || door.getCoordY() != door.getCoordY2())
				((client)player).replaceObject(0, door.getCoordX(), door.getCoordY(), 0, 0);
			((client)player).replaceObject(door.getDoorID2(), door.getCoordX2(), door.getCoordY2(), door.getDoorFace2(), 0);
		}
	}
	
	public boolean isDoor(int doorID) {
		return doorIDs.contains(doorID);
	}
	
	private Door getDoor(int doorID, int coordX, int coordY, byte heightLevel) {
		for (Door door : doors) {
			if (door.getHeightLevel() == heightLevel &&
				(door.getCoordX() == coordX &&
				door.getCoordY() == coordY &&
				door.getDoorID1() == doorID) ||
				(door.getCoordX2() == coordX &&
				door.getCoordY2() == coordY &&
				door.getDoorID2() == doorID)) {
				return door;
			}
		}
		return null;
	}
	
	public static DoorService getInstance() { return instance; }
}
